package top.i89ck.common.jqgrid;

import java.lang.reflect.Method;
import java.util.List;

import com.jfinal.aop.Aop;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import top.i89ck.modules.model.Option;
import top.i89ck.modules.model.User;
import top.i89ck.modules.service.OptionService;
import top.i89ck.modules.utils.Const;

import cn.hutool.core.util.StrUtil;
import top.i89ck.modules.utils.Subject;

/**
 * 加载JqGrid 表格的通用处理方案
 *
 * @author liyingfu
 */
public class JqGridInterceptor implements Interceptor {

    private final OptionService optService = Aop.get(OptionService.class);
    private Controller controller;

    /**
     * jQGrid 的各种页面模板的存放位置
     */
    protected static final String JQ_GRID_TEMPLATE_BASE_PATH = "/template/jqgrid/tables/";

    @Override
    public void intercept(Invocation inv) {
        inv.invoke();

        Method method = inv.getMethod();
        if (method.isAnnotationPresent(View.class)) {
            String viewPath = inv.getReturnValue();
            this.controller = inv.getController();
            setConfiguration(inv.getActionKey());
            View view = method.getAnnotation(View.class);

            switch (view.mode()) {
                case PlainPage:
                    if (StrUtil.isNotBlank(viewPath)) {
                        this.controller.render(viewPath);
                    }
                    break;
                case TreeTable:
                    if (StrUtil.isBlank(viewPath)) {
                        this.controller.render(JQ_GRID_TEMPLATE_BASE_PATH + "tree_table.html");
                    } else {
                        this.controller.render(viewPath);
                    }
                    break;
                case GridTable:
                    if (StrUtil.isBlank(viewPath)) {
                        this.controller.render(JQ_GRID_TEMPLATE_BASE_PATH + "grid_table.html");
                    } else {
                        this.controller.render(viewPath);
                    }
                    break;
                default:
                    break;
            }
        }

    }

    /**
     * 设置全局的基础配置
     *
     * @param actionKey 当前访问的页面
     */
    private void setConfiguration(String actionKey) {
        User sessionUser = Subject.getSessionUser();
        Option option = controller.getAttr(Const.CFG_OPTION);
        if (null == option) {
            option = optService.getOptionByUrl(StrUtil.removePrefix(actionKey, "/"));
            controller.set(Const.CFG_OPTION, option);
        }
        if (null != option) {
            controller.set("option", option);
            switch (sessionUser.getType()) {
                // 超级管理员不做任何过滤
                case Const.USER_TYPE_SUPER:
                    setFunc(option);
                    break;
                // 普通账号需要根据登陆账号进行过滤处理
                case Const.USER_TYPE_DEFAULT:
                    setFunc(option, sessionUser);
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 设置具体员工的功能权限
     *
     * @param option
     * @param sessionUser
     */
    private void setFunc(Option option, User sessionUser) {
        List<Option> btns = optService.getAllSubOptionsByRoleId(option.getId(), Const.DICT_OPTION_TYPE_FUNC_BTNS, sessionUser.getRoleId());
        this.controller.set("btns", btns);
        List<Option> cols = optService.getAllSubOptionsByRoleId(option.getId(), Const.DICT_OPTION_TYPE_FUNC_COLS, sessionUser.getRoleId());
        this.controller.set("cols", cols);
        Option table = optService.getFirstSubOptionByRoleId(Const.DICT_OPTION_TYPE_FUNC_COLS, option.getId(), sessionUser.getRoleId());
        this.controller.set("table", null == table ? new Option() : table);
        List<Option> paras = optService.getAllSubOptionsByRoleId(option.getId(), Const.DICT_OPTION_TYPE_FUNC_FIND, sessionUser.getRoleId());
        this.controller.set("paras", paras);
    }

    /**
     * 设置开发的功能权限信息
     *
     * @param option
     */
    private void setFunc(Option option) {
        List<Option> btns = optService.getAllSubOptions(option.getId(), Const.DICT_OPTION_TYPE_FUNC_BTNS);
        this.controller.set("btns", btns);
        List<Option> cols = optService.getAllSubOptions(option.getId(), Const.DICT_OPTION_TYPE_FUNC_COLS);
        this.controller.set("cols", cols);
        Option table = optService.getFirstSubOptionByDictType(Const.DICT_OPTION_TYPE_FUNC_COLS, option.getId());
        this.controller.set("table", null == table ? new Option() : table);
        List<Option> paras = optService.getAllSubOptions(option.getId(), Const.DICT_OPTION_TYPE_FUNC_FIND);
        this.controller.set("paras", paras);
    }


}
